package com.ruoyi.framework.web.service;

import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.AppUser;
import com.ruoyi.common.core.domain.model.LoginAppUser;
import com.ruoyi.common.core.domain.model.WXLoginDTO;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.WXUtil;
import com.ruoyi.common.utils.http.HttpUtils;
import com.ruoyi.common.utils.ip.IpUtils;
import com.ruoyi.system.service.IAppUserService;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

import static com.ruoyi.common.utils.WXUtil.getStringRandom;

/**
 * 登录校验方法
 *
 * @author ruoyi
 */
@Slf4j
@Component
public class AppLoginService {
    protected final Logger logger = LoggerFactory.getLogger(this.getClass());
    @Resource
    private AppTokenService appTokenService;
    @Resource
    private IAppUserService appUserService;
    @Value("${wx.minApp.appId}")
    private String appId;
    @Value("${wx.minApp.appSecret}")
    private String appSecret;


    /**
     * 登录验证
     *
     * @param username 用户名
     * @param password 密码
     * @return 结果
     */
    public String login(String username, String password,String code,String uuid) {
        AppUser appUser = appUserService.selectAppUserByUserName(username);
        if (appUser == null) {
            throw new ServiceException("用户不存在");
        }
        if (!appUserService.checkPassword(password, appUser.getSalt(), appUser.getPassword())) {
            throw new ServiceException("密码不正确");
        }
        LoginAppUser loginAppUser = new LoginAppUser(appUser.getUserId(), appUser);
        recordLoginInfo(loginAppUser.getUserId());
        // 生成token
        return appTokenService.createAppToken(loginAppUser);
    }
    /**
     * 小程序登录
     * @param wxLoginBody
     * @return
     */
    public AjaxResult minLogin(WXLoginDTO wxLoginBody) {

        String code = wxLoginBody.getCode();
        //秘钥
        String encryptedIv = wxLoginBody.getEncryptedIv();
        //加密数据
        String encryptedData = wxLoginBody.getEncryptedData();
        //1根据code执行小程序登录获取 openId
        String url = "https://api.weixin.qq.com/sns/jscode2session?appid={0}&secret={1}&js_code={2}&grant_type=authorization_code";
        String replaceUrl = url.replace("{0}",appId).replace("{1}",appSecret).replace("{2}",code);
        System.out.println(replaceUrl);
        JSONObject jsonObject = JSONObject.parseObject(HttpUtils.sendGet(replaceUrl));
        if(jsonObject.get("errcode")!=null){
            throw new ServiceException(String.format("获取微信授权信息失败，错误编码：%s，错误信息：%s",String.valueOf(jsonObject.get("errcode")),(String)jsonObject.get("errmsg")));
        }
        String sessionKey = jsonObject.getString("session_key");
        String openid = String.valueOf(jsonObject.get("openid"));
        String decryptResult = "";
        AjaxResult ajax;
        try {
            //如果没有绑定微信开放平台，解析结果是没有unionid的。
            decryptResult = WXUtil.decrypt(sessionKey, encryptedIv, encryptedData);

        } catch (Exception e) {
            log.error(e.getMessage());
            return AjaxResult.error("微信登录失败！");
        }
        if (StringUtils.hasText(decryptResult)) {
            //如果解析成功,获取token
            String token = wxLoginGetToken(decryptResult);
            ajax = AjaxResult.success();
            ajax.put(Constants.TOKEN, token);
            return ajax;
        } else {
            return AjaxResult.error("微信登录失败！");
        }
    }

    private String wxLoginGetToken(String decryptResult) {
        //字符串转json
        JSONObject jsonObject = JSONObject.parseObject(decryptResult);
        //获取openId
        String openId = jsonObject.getString("openId");
        log.info("openid:【{}】",openId);
        //获取nickName
        String nickName = jsonObject.getString("nickName");// 生成16位随机昵称
        //获取头像
        String avatarUrl = jsonObject.getString("avatarUrl");
        String userName = getStringRandom(16);
        //2根据openId判断用户是否存在 不存在自动注册 openId对应数据库表user_name
        AppUser appUser = appUserService.selectAppUserByOpenid(String.valueOf(jsonObject.get("openId")));
        if (appUser == null) {
            appUser = new AppUser();
            appUser.setUserName(userName);
            appUser.setNickName(nickName);
            appUser.setAvatar(avatarUrl);
            appUser.setOpenid(openId);
            appUser.setCreateTime(DateUtils.getNowDate());
            appUserService.insertAppUser(appUser);
        }
        //3生成token
        LoginAppUser loginAppUser = new LoginAppUser(appUser.getUserId(), appUser);
        recordLoginInfo(loginAppUser.getUserId());
        return appTokenService.createAppToken(loginAppUser);
    }

    /**
     * 记录登录信息
     *
     * @param userId 用户ID
     */
    private void recordLoginInfo(Long userId) {
        AppUser appUser = new AppUser();
        appUser.setUserId(userId);
        appUser.setLoginIp(IpUtils.getIpAddr());
        appUser.setLoginDate(DateUtils.getNowDate());
        appUserService.updateAppUser(appUser);
    }
}
